package com.log.demo.filter;

import com.alibaba.fastjson.JSON;
import com.log.demo.common.log.LogTag;
import com.log.demo.common.httpWapper.RequestWrapper;
import com.log.demo.common.httpWapper.ResponseWrapper;
import com.log.demo.dto.ResultMsg;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.UUID;

/**
 * @author weijinhao
 * @date 2023/11/18 17:19
 */

@Component
@Slf4j
public class AccessFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        ResponseWrapper responseWrapper = new ResponseWrapper((HttpServletResponse)response);
        RequestWrapper requestWrapper = new RequestWrapper((HttpServletRequest) request);
        // 获取请求路径
        String path = requestWrapper.getRequestURI();
        String traceId = requestWrapper.getHeader(LogTag.traceIdName);
        String caller = requestWrapper.getHeader(LogTag.caller_func);
        if(traceId == null) {
            traceId = UUID.randomUUID().toString().replace("-","");
        }
        MDC.put(LogTag.caller_func,caller);
        MDC.put(LogTag.callee_func,path);
        MDC.put(LogTag.traceIdName,traceId);
        MDC.put(LogTag.spanIdName, UUID.randomUUID().toString().replace("-","").substring(0,25));
        long startTime = System.currentTimeMillis();
        MDC.put(LogTag.dltag,LogTag._com_request_in);

        log.info(requestWrapper.getRequestBody());
        try {
            MDC.put(LogTag.dltag,LogTag._undef);
            chain.doFilter(requestWrapper, responseWrapper);
        } finally {
            String content = new String(responseWrapper.getResponseData(), "utf-8");
            ResultMsg resultMsg = JSON.parseObject(content, ResultMsg.class);
            long endTime = System.currentTimeMillis();
            MDC.put(LogTag.proc_time,Long.toString(endTime - startTime));
            MDC.put(LogTag.errno,Integer.toString(resultMsg.getErrorCode()));
            MDC.put(LogTag.errmsg,resultMsg.getErrorMsg());
            MDC.put(LogTag.dltag,LogTag._com_request_out);
            log.info(content);
            MDC.clear();
            response.getWriter().write(content);
        }
    }


    private static class MyPrintWriter extends PrintWriter {
        public MyPrintWriter(Writer out) {
            super(out);
        }

        @Override
        public String toString() {
            return super.out.toString();
        }
    }
}